﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using NPOI.XWPF.UserModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using WeihanLi.Extensions;

namespace CommandLib
{
    /// <summary>
    /// HTTP请求帮助类
    /// </summary>
    public static class HttpHelper
    {
        /// <summary>
        /// GET请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="header"></param>
        /// <returns></returns>
        public static string Get(string url, Dictionary<string, string> header = null)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            if (!string.IsNullOrWhiteSpace(url))
            {

                if (header != null)
                {
                    httpClientFactory.DefaultRequestHeaders.Clear();
                    foreach (var item in header)
                    {
                        httpClientFactory.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }

                }
                try
                {
                    var rdata = httpClientFactory.GetAsync(url).Result;
                    if (rdata.IsSuccessStatusCode)
                    {
                        result = rdata.Content.ReadAsStringAsync().Result;
                    }
                    else
                    {
                        throw new Exception($"ErrorCode:{rdata.StatusCode}");
                    }

                }
                catch (Exception)
                {
                    throw;
                }
                finally { httpClientFactory.Dispose(); }

            }
            return result;
        }
        /// <summary>
        /// 异步方法
        /// </summary>
        /// <param name="url"></param>
        /// <param name="header"></param>
        /// <returns></returns>
        public static async Task<string> GetAsync(string url, Dictionary<string, string> header = null)
        {
            var httpClientFactory = HttpClientFactory.Create();
            string result = string.Empty;
            if (!string.IsNullOrWhiteSpace(url))
            {
                if (header != null)
                {
                    httpClientFactory.DefaultRequestHeaders.Clear();
                    foreach (var item in header)
                    {
                        httpClientFactory.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                try
                {
                    var rdata = await httpClientFactory.GetAsync(url);
                    if (rdata.IsSuccessStatusCode)
                    {
                        result = await rdata.Content.ReadAsStringAsync();
                    }
                    else
                    {
                        throw new Exception($"ErrorCode:{rdata.StatusCode}");
                    }

                }
                catch (Exception)
                {
                    throw;
                }
                finally { httpClientFactory.Dispose(); }

            }
            return result;
        }
        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="header">消息头</param>
        /// <returns></returns>
        public static async Task<HttpResponseMessage> GetSendAsync(string url, Dictionary<string, string> header = null)
        {
            var result = new HttpResponseMessage();
            var httpClientFactory = HttpClientFactory.Create();
            if (!string.IsNullOrWhiteSpace(url))
            {
                if (header != null)
                {
                    httpClientFactory.DefaultRequestHeaders.Clear();
                    foreach (var item in header)
                    {
                        httpClientFactory.DefaultRequestHeaders.Add(item.Key, item.Value);
                    }
                }
                try
                {
                    result = await httpClientFactory.GetAsync(url);
                }
                catch (Exception)
                {
                    throw;
                }
                finally { httpClientFactory.Dispose(); }

            }
            return result;
        }

        /// <summary>
        /// POST表单请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="param">表单参数</param>
        /// <returns></returns>
        public static string Post(string url, Dictionary<string, object> param = null)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            StringBuilder sb = new StringBuilder();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            if (param != null)
            {
                foreach (var item in param)
                {
                    sb.Append($"{item.Key}={item.Value}&");
                }
            }
            try
            {
                var httpcoment = new StringContent(sb?.ToString().TrimEnd('&'), Encoding.UTF8);
                var rdata = httpClientFactory.PostAsync(url, httpcoment).Result;
                if (rdata.IsSuccessStatusCode)
                {
                    result = rdata.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }

            return result;

        }
        /// <summary>
        /// POST表单请求数据请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="param">请求参数</param>
        /// <param name="ContxtType">请求类型</param>
        /// <param name="valuePairs">请求头</param>
        /// <returns></returns>
        public static string PostSend(string url, Dictionary<string, object> param = null, string ContxtType = "application/x-www-form-urlencoded", HeaderDictionary valuePairs = null)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            StringBuilder sb = new StringBuilder();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue(ContxtType) { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            if (valuePairs != null)
            {
                valuePairs.ForEach(f =>
                {
                    httpClientFactory.DefaultRequestHeaders.Add(f.Key, f.Value.ToString());
                });
            }
            if (ContxtType.ToLower() == "application/json")
            {
                if (param != null)
                {
                    sb.Append(param.ToJsonString());
                }
                else
                {
                    sb.Append("{}");
                }

            }
            else
            {
                if (param != null)
                {
                    foreach (var item in param)
                    {
                        sb.Append($"{item.Key}={item.Value}&");
                    }
                }
            }

            try
            {
                var httpcoment = new StringContent(sb.ToString().TrimEnd('&'), Encoding.UTF8);
                var rdata = httpClientFactory.PostAsync(url, httpcoment).Result;
                if (rdata.IsSuccessStatusCode)
                {
                    result = rdata.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally { httpClientFactory.Dispose(); }

            return result;

        }

        /// <summary>
        /// Http发起数据请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="Method">请求类型：GET,PUT,POST,DELETE</param>
        /// <param name="param">请求参数</param>
        /// <param name="ContxtType">请求类型</param>
        /// <param name="valuePairs">请求头</param>
        /// <returns></returns>
        public static async Task<HttpResponseMessage> HttpSend(string url, string Method, string param = "", string ContxtType = "application/x-www-form-urlencoded", HeaderDictionary valuePairs = null)
        {

            var result = new HttpResponseMessage();
            var httpClientFactory = HttpClientFactory.Create();
            StringBuilder sb = new StringBuilder();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue(ContxtType) { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);

            valuePairs?.ForEach(f =>
            {
                httpClientFactory.DefaultRequestHeaders.Add(f.Key, f.Value.ToString());
            });

            if (ContxtType.ToLower() == "application/json")
            {
                if (!param.IsEmpty())
                {
                    sb.Append(param);
                }
                else
                {
                    sb.Append("{}");
                }

            }
            else
            {
                if (param != null)
                {
                    sb.Append(param);
                }
            }

            try
            {
                //请求参数
                var httpcoment = new StringContent(sb.ToString(), Encoding.UTF8);
                switch (Method.ToUpper())
                {
                    case "GET":
                        result = await httpClientFactory.GetAsync(url);
                        break;
                    case "POST":
                        result = await httpClientFactory.PostAsync(url, httpcoment);
                        break;
                    case "PUT":
                        result = await httpClientFactory.PutAsync(url, httpcoment);
                        break;
                    case "DELETE":
                        result = await httpClientFactory.DeleteAsync(url);
                        break;
                    case "PATCH":
                        result = await httpClientFactory.PatchAsync(url, httpcoment);
                        break;
                    default:
                        throw new Exception("Method not Fund!");

                }
            }
            catch (Exception)
            {
                throw;
            }
            finally { httpClientFactory.Dispose(); }

            return result;

        }

        /// <summary>
        /// POST表单请求数据请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="param">请求参数</param>
        /// <param name="ContxtType">请求类型</param>
        /// <param name="valuePairs">请求头</param>
        /// <returns></returns>
        public static async Task<HttpResponseMessage> PostAsync(string url, string param = "", string ContxtType = "application/x-www-form-urlencoded", HeaderDictionary valuePairs = null)
        {
            var result = new HttpResponseMessage();
            var httpClientFactory = HttpClientFactory.Create();

            StringBuilder sb = new StringBuilder();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue(ContxtType) { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            if (valuePairs != null)
            {
                valuePairs.ForEach(f =>
                {
                    httpClientFactory.DefaultRequestHeaders.Add(f.Key, f.Value.ToString());
                });
            }
            if (ContxtType.ToLower() == "application/json")
            {
                if (!param.IsEmpty())
                {
                    sb.Append(param);
                }
                else
                {
                    sb.Append("{}");
                }

            }
            else
            {
                if (param != null)
                {
                    sb.Append(param);
                }
            }

            try
            {
                var httpcoment = new StringContent(sb.ToString(), Encoding.UTF8);
                result = await httpClientFactory.PostAsync(url, httpcoment);
            }
            catch (Exception)
            {
                throw;
            }
            finally { httpClientFactory.Dispose(); }

            return result;

        }
        /// <summary>
        /// 异步方法
        /// </summary>
        /// <param name="url"></param>
        /// <param name="param"></param>
        /// <returns></returns>
        public static async Task<string> PostAsync(string url, Dictionary<string, object> param = null)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            StringBuilder sb = new StringBuilder();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/x-www-form-urlencoded") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            if (param != null)
            {
                foreach (var item in param)
                {
                    sb.Append($"{item.Key}={item.Value}&");
                }
            }
            try
            {
                var httpcoment = new StringContent(sb?.ToString().TrimEnd('&'), Encoding.UTF8);
                var rdata = await httpClientFactory.PostAsync(url, httpcoment);
                if (rdata.IsSuccessStatusCode)
                {
                    result = await rdata.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }

            return result;

        }
        /// <summary>
        /// POST以JSON类型请求
        /// </summary>
        /// <param name="url">地址</param>
        /// <param name="param">对象</param>
        /// <returns></returns>
        public static string PostJson(string url, object param)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            var paramJosn = string.Empty;
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            try
            {
                paramJosn = param == null ? "{}" : JsonConvert.SerializeObject(param);
                var httpcoment = new StringContent(paramJosn, Encoding.UTF8);
                var rdata = httpClientFactory.PostAsync(url, httpcoment).Result;
                if (rdata.IsSuccessStatusCode)
                {
                    result = rdata.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }
            return result;
        }
        public static async Task<string> PostJsonAsync(string url, object param)
        {
            var httpClientFactory = HttpClientFactory.Create();
            var result = string.Empty;
            var paramJosn = string.Empty;
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            try
            {
                paramJosn = param == null ? "{}" : JsonConvert.SerializeObject(param);
                var httpcoment = new StringContent(paramJosn, Encoding.UTF8);
                var rdata = await httpClientFactory.PostAsync(url, httpcoment);
                if (rdata.IsSuccessStatusCode)
                {
                    result = await rdata.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }
            return result;
        }
        /// <summary>
        /// Post以JSON字符串类型请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static string PostJson(string url, string json)
        {

            var result = string.Empty;
            var httpClientFactory = HttpClientFactory.Create();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            try
            {
                json = json ?? "{}";
                var httpcoment = new StringContent(json, Encoding.UTF8);
                var rdata = httpClientFactory.PostAsync(url, httpcoment).Result;
                if (rdata.IsSuccessStatusCode)
                {
                    result = rdata.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }
            return result;
        }
        /// <summary>
        /// 异步JOSN请求
        /// </summary>
        /// <param name="url"></param>
        /// <param name="json"></param>
        /// <returns></returns>
        public static async Task<string> PostJsonAsync(string url, string json)
        {

            var result = string.Empty;
            var httpClientFactory = HttpClientFactory.Create();
            httpClientFactory.DefaultRequestHeaders.Accept.Clear();
            var mwh = new MediaTypeWithQualityHeaderValue("application/json") { CharSet = "utf-8" };
            httpClientFactory.DefaultRequestHeaders.Accept.Add(mwh);
            try
            {
                json = json ?? "{}";
                var httpcoment = new StringContent(json, Encoding.UTF8);
                var rdata = await httpClientFactory.PostAsync(url, httpcoment);
                if (rdata.IsSuccessStatusCode)
                {
                    result = await rdata.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception($"ErrorCode:{rdata.StatusCode}");
                }
            }
            catch (Exception)
            {

                throw;
            }
            finally { httpClientFactory.Dispose(); }
            return result;
        }


        /// <summary>
        /// 获取消息体
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public static string GetBody(this HttpRequest request)
        {
            var result = string.Empty;
            if (request != null)
            {
                byte[] bytes = new byte[request.Body.Length];
                request.Body.Write(bytes, 0, bytes.Length);
                result = Encoding.UTF8.GetString(bytes);
            }
            return result;
        }
    }
}
